
declare function readCookie(name);
declare function createCookie(name,value,days);

var resCfg = {
	"resources": [
		{ "name": "bkcn", "type": "image", "url": "assets/bkcn.png" },
		{ "name": "bkjp", "type": "image", "url": "assets/bkjp.png" },
		{ "name": "bktitle", "type": "image", "url": "assets/title.jpg" },
        { "name": "bkmusic", "type":"sound", "url":"assets/bkmusic.mp3"},
        { "name": "sound_over", "type":"sound", "url":"assets/sound_over.wav"},
        { "name": "sound_good", "type":"sound", "url":"assets/sound_good.wav"},
        { "name": "sound_bad", "type":"sound", "url":"assets/sound_bad.wav"}
	],
	"groups": [
		{
			"name": "preload",
			"keys": "sound_good,sound_bad,sound_over,bkcn,bkjp,bktitle"
		}
	]
};


class Main extends egret.Sprite {

    private loadingView : LoadingUI;
    private textfield : egret.TextField;
    private panResult;
    private labResult;

    public static boxRow:number = 5;
    public static boxCol:number = 5;
    private boxes:any[][];

    private killEnemy:number = 0;
    private rankData;
    private soundGood:egret.Sound;
    private soundBad:egret.Sound;

    private _lockMove:number = 0;
    private curState:String;
    private browserVersion = getBrowserVersion();

    public constructor() {
        super();
        this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
    }

    private onAddToStage(event:egret.Event) {

        this.loadingView = new LoadingUI(this);
        this.stage.addChild(this.loadingView);

        this.touchEnabled = true;
        this.width = this.stage.stageWidth;
        this.height = this.stage.stageHeight;
        this.graphics.beginFill(0x666666, 0.95);
        this.graphics.drawRect(0, 0, this.width, this.height);
        this.graphics.endFill();
        //console.log("add to stage", this.width, this.height, this.touchEnabled);

        for(var i=1;i<12;i++)
        {
            var lv = Math.pow(2,i);
            resCfg["resources"].push({ "name": "level"+lv+"j", "type": "image", "url": "assets/"+lv+"j.png" });
            resCfg["resources"].push({ "name": "level"+lv+"c", "type": "image", "url": "assets/"+lv+"c.png" });
            resCfg["groups"][0]["keys"] += ",level"+lv+"c,level"+lv+"j";
        }
        RES.parseConfig(resCfg, "resource/");
        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
        RES.loadGroup("preload");
    }

    private onResourceLoadComplete(event:RES.ResourceEvent):void {
        if (event.groupName == "preload") {
            RES.removeEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);

            this.createGameScene();
            //this.playMusic();
        }
    }

    private onResourceLoadError(event:RES.ResourceEvent):void {
        console.warn("Group:" + event.groupName + " has failed to load");
        this.onResourceLoadComplete(event);
    }

    private onResourceProgress(event:RES.ResourceEvent):void {
        if (event.groupName == "preload") {
            this.loadingView.setProgress(event.itemsLoaded, event.itemsTotal);
        }
    }

    public playMusic(){
        RES.getResAsync("bkmusic", function(data,key){
            var sound:egret.Sound = data;
            sound.volume = 0.5;
            sound.play(true);
        }, this);
    }

    //--------------------------------
    private needMove:boolean;
    private downPoint:egret.Point;
    private movePoint:egret.Point;

    public get lockMove(){ return this._lockMove; }
    public set lockMove(v:number){
        if( this._lockMove>0 && v==0 )
        {
            this.saveGame();
        }
        this._lockMove = v;
        //console.log(v)
    }

    private mouseDownHandle(event:egret.TouchEvent):void
    {
        this.addEventListener(egret.TouchEvent.TOUCH_MOVE,this.stage_mouseMoveHandler,this);
        this.addEventListener(egret.TouchEvent.TOUCH_END,this.stage_mouseUpHandler,this);
        this.addEventListener(egret.Event.LEAVE_STAGE,this.stage_mouseUpHandler,this);

        this.downPoint = this.globalToLocal(event.stageX, event.stageY);
    }

    private stage_mouseMoveHandler(event:egret.TouchEvent):void{
        if(!this.movePoint)
            this.movePoint = new egret.Point();
        this.movePoint.x = event.stageX;
        this.movePoint.y = event.stageY;
        if (this.needMove)
            return;
        this.needMove = true;
    }

    public stage_mouseUpHandler(event:egret.Event):void{
        this.removeEventListener(egret.TouchEvent.TOUCH_MOVE, this.stage_mouseMoveHandler, this);
        this.removeEventListener(egret.TouchEvent.TOUCH_END, this.stage_mouseUpHandler, this);
        this.addEventListener(egret.Event.LEAVE_STAGE, this.stage_mouseUpHandler, this);
        if(this.needMove){
            this.updateWhenMouseUp();
            this.needMove = false;
        }
    }

    private updateWhenMouseUp():void
    {
        var p:egret.Point = this.globalToLocal(this.movePoint.x, this.movePoint.y ,egret.Point.identity);
        var offSetX:number = p.x - this.downPoint.x;
        var offSetY:number = p.y - this.downPoint.y;

        if(offSetY<0 && Math.abs(offSetY)>Math.abs(offSetX))  //上
        {
            this.doMove(0);
        }
        else if(offSetX>0 && offSetX>Math.abs(offSetY))  //右
        {
            this.doMove(1);
        }
        else if(offSetY>0 && offSetY>Math.abs(offSetX))  //下
        {
            this.doMove(2);
        }
        else if(offSetX<0 && Math.abs(offSetX)>Math.abs(offSetY))  //左
        {
            this.doMove(3);
        }
    }



    private getRank()
    {
        var urlloader = new egret.URLLoader();
        var urlreq:egret.URLRequest;
        urlreq = new egret.URLRequest();

        urlreq.url = "http://ali.19v5.com:10020/api/get_rank?score=";
        urlreq.url += this.killEnemy;

        urlloader.load(urlreq);
        urlloader.addEventListener(egret.Event.COMPLETE, function(event:egret.Event) {
            if( this.curState != "showResult" )
                return;
            console.log(urlloader.data);
            var data:egret.URLVariables = urlloader.data;
            var txt = data.toString();
            var obj = JSON.parse(txt);
            this.showOver(obj.rank, obj.percent)
        },this);
    }

    private showOver(iRank:number=0, iPercent:number=0)
    {
        this.textfield.text = "分享给更多抗日小伙伴吧~";

        var parser:egret.HtmlTextParser = new egret.HtmlTextParser();

        if( this.panResult==null )
        {
            var pan = new egret.Sprite();
            pan.y = Box.offsetY-10;
            pan.width = this.width;
            pan.height = this.height - pan.y;
            pan.graphics.beginFill(0x003366, 0.8);
            pan.graphics.drawRect(0, 0, pan.width, pan.height);
            pan.graphics.endFill();
            pan.touchEnabled = true;
            pan.addEventListener(egret.TouchEvent.TOUCH_BEGIN , function(e:egret.Event){
                e.stopPropagation();
            }, this);
            this.panResult = pan;
            this.addChild(pan);

            var tf = new egret.TextField();
            tf.size = 60;
            tf.width = pan.width;
            tf.height = tf.size*2;
            tf.y = pan.height-tf.height;
            tf.verticalAlign = "middle";
            tf.textAlign = "center";
            tf.text = "再玩一次！";
            tf.background = true;
            tf.backgroundColor = 0x000033;
            tf.textColor = 0xffff00;
            tf.touchEnabled = true;
            tf.addEventListener(egret.TouchEvent.TOUCH_BEGIN , function(e:egret.Event){
                e.stopPropagation();
                this.panResult = null;
                this.removeChild(pan);
                this.resetGame();
            }, this);
            pan.addChild(tf);

            var tf = new egret.TextField();
            tf.size = 50;
            tf.width = pan.width;
            tf.height = pan.height;
            tf.textAlign = "center";

            var text = "\n";
            text += "<font color=#ff0000 size=70 stroke=2><b>致敬！抗日勇士！</b></font>";
            text += "\n\n";
            text += "你消灭了<font color='#ff0000' size=80>"+this.killEnemy+"</font>个鬼子";
            text += "\n\n排名获取中，请稍候...";
            tf.textFlow = parser.parser(text);
            this.labResult = tf;
            pan.addChild(tf);
        }


        if( iRank>0 ){
            var rankd = this.killEnemy;
            if( rankd<100 ) rankd = 0;
            var rank = (rankd)/1500*100
            var text = "\n";
            text += "<font color=#ff0000 size=70 stroke=2><b>致敬！抗日勇士！</b></font>";
            text += "\n\n";
            text += "你消灭了<font color='#ff0000' size=80>"+this.killEnemy+"</font>个鬼子";
            text += "\n\n";
            if( iRank<100 )
                text += "排名第<font color='#ff0000' size=80>"+iRank+"</font>名";
            else
                text += "还排不上号，继续努力～";
            text += "\n\n";
            text += "超过了<font color='#ff0000' size=80>"+iPercent+"%</font>的小伙伴";
            this.labResult.textFlow = parser.parser(text);
            document.title = "为抗战阅兵点赞！我消灭了"+this.killEnemy+"个鬼子！超过了"+iPercent+"%的小伙伴！不服来战！";
        }


    }

    private checkOver():boolean{
        for( var c=0; c<Main.boxCol; c++ )
        {
            var dataList1 = [];
            var dataList2 = [];
            for( var r=0; r<Main.boxRow; r++ )
            {
                var n1 =  Main.boxRow-r-1
                var n2 =  r
                dataList1[n1] = this.boxes[r][c];
                dataList2[n1] = this.boxes[r][c];
            }
            if( this.getLineResult(dataList1)["moved"]>0 || this.getLineResult(dataList2)["moved"]>0 )
                return false;
        }

        for( var r=0; r<Main.boxRow; r++ )
        {
            var dataList1 = []
            var dataList2 = []
            for( var c=0; c<Main.boxCol; c++ )
            {
                var n1 = c
                var n2 = Main.boxCol-c-1
                dataList1[n1] = this.boxes[r][c];
                dataList2[n2] = this.boxes[r][c];
            }
            if( this.getLineResult(dataList1)["moved"]>0 || this.getLineResult(dataList2)["moved"]>0 )
                return false;
        }
        return true
    }

    private doMove(direction:number):void
    {
        if( this.lockMove>0 ) {
            console.log("lockMove", this.lockMove);
            return;
        }
        var oldKillEnemy = this.killEnemy;

        if( direction==0 || direction==2)
        {
            for( var c=0; c<Main.boxCol; c++ )
            {
                var dataList = []
                for( var r=0; r<Main.boxRow; r++ )
                {
                    var n = direction==0 ? r : Main.boxRow-r-1
                    dataList[n] = this.boxes[r][c];
                }
                //console.log("check move in col:", c);
                this.processLine(dataList);
            }
        }
        else if( direction==1 || direction==3 )
        {
            for( var r=0; r<Main.boxRow; r++ )
            {
                var dataList = []
                for( var c=0; c<Main.boxCol; c++ )
                {
                    var n = direction==3 ? c : Main.boxCol-c-1
                    dataList[n] = this.boxes[r][c];
                }
                //console.log("check move in row:", r);
                this.processLine(dataList);
            }
        }

        var parser:egret.HtmlTextParser = new egret.HtmlTextParser();
        this.textfield.textFlow = parser.parser("你消灭了<font color=#ff0000 size=70>"+this.killEnemy+"</font>个鬼子");
        document.title = "为抗战阅兵点赞！我消灭了"+this.killEnemy+"个鬼子！不服来战！";

        if( LoadingUI.isSoundOn() && !this.isAndroidQQ() )
            ((this.killEnemy>oldKillEnemy) ? this.soundGood:this.soundBad).play();

        if( this.checkOver() )
        {
            if( LoadingUI.isSoundOn() && !this.isAndroidQQ() )
                RES.getRes("sound_over").play();

            this.curState = "showResult";
            this.showOver();
            this.getRank();
            createCookie("lastGame","",-1);
        }
    }

    private saveGame() {
        var gameState = {};
        for(var r=0;r<Main.boxRow;r++)
        {
            gameState[r] = [];
            for(var c=0;c<Main.boxCol;c++)
            {
                var box = this.boxes[r][c]
                gameState[r][c] = [box.level, box.side];
            }
        }
        var save = {
        state:gameState,
        killEnemy:this.killEnemy
        };
        var ss = JSON.stringify(save);
        createCookie("lastGame",ss,1);
        console.log("save", ss);
    }

    private processLine(dataList:Array<Box>){
        var ret = this.getLineResult(dataList);
        this.performChanges(dataList, ret["changes"]);

        this.killEnemy += ret["killEnemy"];
    }

    private getLineResult(dataList:Array<Box>):Object{
        var moved = 0;
        var changes = [];
        var killEnemy = 0;
        for( var r=0; r<dataList.length; r++ )
        {
            var b = dataList[r];
            var bn = (r<dataList.length-1) ? dataList[r+1] : undefined;
            if( bn==undefined )
            {
                changes[r] = r-moved;
                //console.log(r, "->", changes[r]);
            }
            else if( b.level == bn.level )
            {
                if( b.side!=bn.side && bn.side==0 )
                    killEnemy += b.level;

                changes[r] = -1;
                changes[r+1] = r-moved;
                //console.log(r, "->", -1);
                //console.log(r+1, "->", changes[r+1], "=", 2*b.level);
                moved++;
                r++;
            }
            else
            {
                changes[r] = r-moved;
                //console.log(r, "->", changes[r]);
            }
        }
        var ret = {
        "changes" : changes,
        "killEnemy" : killEnemy,
        "moved" : moved,
        }
        return ret;
    }

    private performChanges(dataList:Array<Box>, changes:Array<number>)
    {
        var source = [];
        for( var r=0; r<dataList.length; r++ ) source[r] = -1;
        for( var r=0; r<dataList.length; r++ )
        {
            if( changes[r] != -1 )
                source[changes[r]] = r;
        }


        for(var r=0; r<changes.length; r++)
        {
            var smode = {}; //检查自己的变化
            if( changes[r]==r ) //不动
            {
                smode["move"] = 0;
            }
            else if( changes[r]==-1 ) //消失
            {
                smode["move"] = -1;
            }
            else //移走
            {
                var bt = dataList[changes[r]];
                smode["move"] = 1;
                smode["x"] = bt.x;
                smode["y"] = bt.y;
            }

            var nmode = {}; //检查新来的
            if( source[r]==r ) //不动
            {
                nmode["new"] = 0;
            }
            else if( source[r]==-1 ) //没有
            {
                nmode["new"] = -1;
            }
            else //有新来的
            {
                var bs = dataList[source[r]];
                var up = changes[source[r]-1]==-1;
                nmode["new"] = 1;
                nmode["level"] = bs.level*(up?2:1);
                nmode["side"] = bs.side;
            }

            dataList[r].perform(this, smode, nmode);
        }
    }



    private createGameScene():void {
        this.addEventListener(egret.TouchEvent.TOUCH_BEGIN , this.mouseDownHandle , this);

        this.soundGood = RES.getRes("sound_good");
        this.soundBad = RES.getRes("sound_bad");

        this.boxes = [];
        for(var r=0;r<Main.boxRow;r++)
        {
            this.boxes[r] = [];
            for(var c=0;c<Main.boxCol;c++)
            {
                var box = new Box(r, c);
                this.addChild(box);
                this.boxes[r][c] = box;
            }
        }

        var imgTitle = new egret.Bitmap();
        imgTitle.texture = RES.getRes("bktitle");
        imgTitle.alpha = 0.5;
        this.addChild(imgTitle);

        var textfield = new egret.TextField();
        textfield.width = this.width;
        textfield.height = Box.offsetY-5;
        textfield.verticalAlign = "middle";
        textfield.textAlign = "center";
        textfield.size = 50;
        textfield.stroke = 2;
        textfield.strokeColor = 0x000000;
        textfield.touchEnabled = true;
        textfield.addEventListener(egret.TouchEvent.TOUCH_TAP , function(e){
            e.stopPropagation();
        }, this);
        this.textfield = textfield;
        this.addChild(textfield);
        console.log(textfield.height);

        var ar = null;
        var lastGame = readCookie("lastGame");
        if( lastGame!=null )
        {
            console.log("load", lastGame);
            ar = JSON.parse(lastGame);
        }

        this.resetGame(ar);
    }


    public data:number[][];
    public resetGame(ar=null):void{
        if(ar)
        {
            var parser:egret.HtmlTextParser = new egret.HtmlTextParser();
            var state = ar["state"];
            for(var r=0;r<Main.boxRow;r++)
            {
                for(var c=0;c<Main.boxCol;c++)
                {
                    var box = this.boxes[r][c];
                    var bs = state[r][c];
                    box.reset(bs[0], bs[1]);
                }
            }
            this.killEnemy = ar["killEnemy"];
            this.textfield.textFlow = parser.parser("你消灭了<font color=#ff0000 size=70>"+this.killEnemy+"</font>个鬼子");
        }
        else
        {

            for(var r=0;r<Main.boxRow;r++)
            {
                for(var c=0;c<Main.boxCol;c++)
                {
                    var box = this.boxes[r][c];
                    box.reset();
                }
            }
            this.killEnemy = 0;
            this.textfield.text = "准备好消灭鬼子了吗？\n指挥国军，撞死它们！";
        }
        this.curState = "playing";
    }

    private isAndroidQQ(){
        return  this.browserVersion["android"] && (this.browserVersion["qq"]||this.browserVersion["weixin"]);
    }
}


